using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using System.Xml;
using System.Xml.Serialization;
using System.IO;
using R2ML;

namespace EventAbstractionAPI.RuleTableCtrl
{
    public partial class RuleTableCtrl : UserControl
    {

        public delegate void UpdateHandler ();
        public event UpdateHandler ViewUpdateOccured;
        public Boolean updatingOnUserEdit = false;

        public RuleTableCtrl()
        {
            InitializeComponent();
        }
        
        private void RuleTableCtrl_Load(object sender, EventArgs e)
        {
            hideConditionColumns();
        }

        private void ClearUI()
        {
            _drawnRuleCount = 0;
            tableLayoutPanel1.SuspendLayout();
            tableLayoutPanel1.Controls.Clear();

            this._controls = new Control[8];

            this._controls[0] = new Label();
            this._controls[0].Text = "Id";

            this._controls[1] = new Label();
            this._controls[1].Text = "Event obj set";

            this._controls[2] = new Label();
            this._controls[2].Text = "Event src";

            this._controls[3] = new Label();
            this._controls[3].Text = "Condition";

            this._controls[4] = new Label();
            this._controls[4].Text = "Action Obj Set";

            this._controls[5] = new Label();
            this._controls[5].Text = "Action Call";

            this._controls[6] = new Label();
            this._controls[6].Text = "Action Parameters";

            this._controls[7] = new Label();
            this._controls[7].Text = "Postcondition";

            for (int i = 0; i < 8; i++)
            {
                this.tableLayoutPanel1.Controls.Add(this._controls[i], i, 0);
            }
            tableLayoutPanel1.ResumeLayout();
        }

        private void UpdateUIControls()
        {
            String eventSrc, theEvent, precondition, actionSource, actionCall, actionParameters, postCondition;

            foreach (ReactionRule rr in RuleFactory.Instance.ruleBase.ruleSet.reactionRuleList)
            {
                eventSrc = rr.triggeringEvent.messageEventExpression.sender;
                theEvent = rr.triggeringEvent.messageEventExpression.eventType;
                precondition = rr.conditions;

                actionParameters = ""; //remove the information from this string that is in there from the previous iteration.

                if (rr.producedAction.invokeActionExpression != null)
                {
                    actionSource = rr.producedAction.invokeActionExpression.contextArguement[0].name;
                }
                else if (rr.producedAction.assignActionExpression != null)
                {
                    actionSource = rr.producedAction.assignActionExpression.contextArguement[0].name;
                }
                else
                {
                    rr.producedAction.assignActionExpression.contextArguement = new ObjectVariable[1];
                    rr.producedAction.assignActionExpression.contextArguement[0] = new ObjectVariable();
                    actionSource = rr.producedAction.assignActionExpression.contextArguement[0].name;
                }

                if (rr.producedAction.invokeActionExpression != null)
                {
                    actionCall = rr.producedAction.invokeActionExpression.operationID + "()";

                    for (int index = 0; index < rr.producedAction.invokeActionExpression.arguements.Length; index++)
                    {
                        if (index > 0)
                        {
                            actionParameters += ", ";
                        }

                        //if this field is a string then put the quotes back in at the start and end.
                        Boolean isString = false;
                        try
                        {
                            isString = (rr.producedAction.invokeActionExpression.arguements[index].datatypeID.ToLower() == "string");
                        } catch (Exception) {}

                        if (isString)
                        {
                            //actionParameters += "\"" + rr.producedAction.invokeActionExpression.arguements[index].lexicalValue + "\"";
                            actionParameters += rr.producedAction.invokeActionExpression.arguements[index].lexicalValue;
                        }
                        else
                        {
                            actionParameters += rr.producedAction.invokeActionExpression.arguements[index].lexicalValue;
                        }
                    }
                }
                else if (rr.producedAction.assignActionExpression != null)
                {
                    actionCall = rr.producedAction.assignActionExpression.propertyID;

                    for (int index = 0; index < rr.producedAction.assignActionExpression.arguements.Length; index++)
                    {
                        if (index>0)
                        {
                            actionParameters += ", ";
                        }

                        //if this field is a string then put the quotes back in at the start and end.
                        if (rr.producedAction.assignActionExpression.arguements[index].datatypeID.ToLower() == "string")
                        {
                            //actionParameters += "\"" + rr.producedAction.assignActionExpression.arguements[index].lexicalValue + "\"";
                            actionParameters += rr.producedAction.assignActionExpression.arguements[index].lexicalValue;
                        }
                        else
                        {
                            actionParameters += rr.producedAction.assignActionExpression.arguements[index].lexicalValue;
                        }
                    }
                }
                else
                {
                    throw new Exception("ActionExpression not present. Check the R2ML file for the ProducedAction");
                }

                
                postCondition = rr.postcondition.objectClassificationAtom.arguements[0].name;

                DrawRule(eventSrc, theEvent, precondition, actionSource, actionCall, actionParameters, postCondition);
            }
        }

        /// <summary>
        /// Create a new blank rule
        /// 
        /// 1. Generate a new row in the table layout
        /// 2. Populate the row with textboxes for each cell in the row
        /// </summary>
        public void NewRule()
        {
            NewRule("", "", "", "", "","","");
            
        }

        /// <summary>
        /// Create an old rule and add it to the diplay. 
        /// 
        /// NOTE: It maynot keep the same ID. The ID is given sequentially and is first in first out
        /// </summary>
        /// <returns>the new ID of the rule</returns>
        public int NewRule(String Event_src, String Event, String Precondition, String actionSource, String actionCall, String Action_parameter, String Postcondition)
        {
            //increment the rule count
            
            //add a reaction rule to the rule data type. This will be used for persistancy and syncronization.
            R2ML.RuleFactory.Instance.addReactionRule(RuleFactory.Instance.ruleBase.ruleSet.reactionRuleList.Count.ToString());

            DrawRule(Event_src, Event, Precondition, actionSource, actionCall, Action_parameter, Postcondition);

            ViewUpdateOccured.Invoke();

            return R2ML.RuleFactory.Instance.ruleBase.ruleSet.reactionRuleList.Count;

        }

        private void DrawRule(String Event_src, String Event, String Precondition, String actionSource, String actionCall, String Action_parameter, String Postcondition)
        {
            ++_drawnRuleCount;

            tableLayoutPanel1.SuspendLayout();

            this._labelInst = new System.Windows.Forms.Label();
            this.tableLayoutPanel1.Controls.Add(this._labelInst, 0, _drawnRuleCount);
            this._labelInst.Text = _drawnRuleCount.ToString();
            this._labelInst.Width = 40;

            this._controls = new Control[8];

            //-----------------Control declarations-----------------------
            this._controls[1] = new Button();

            this._controls[2] = new TextBox();
            //((ComboBoxListCtrl)this.controls[2]).heightChange += new heightChanged(RuleTableCtrl_rowheightChange);

            this._controls[3] = new TextBox();
            ((TextBox)this._controls[3]).Multiline = true;
            ((TextBox)this._controls[3]).Height = 40;

            this._controls[4] = new Button();

            this._controls[5] = new TextBox();
            ((TextBox)this._controls[5]).Multiline = true;
            ((TextBox)this._controls[5]).Height = 40;

            this._controls[6] = new TextBox();
            ((TextBox)this._controls[6]).Multiline = true;
            ((TextBox)this._controls[6]).Height = 40;

            this._controls[7] = new TextBox();
            ((TextBox)this._controls[7]).Multiline = true;
            ((TextBox)this._controls[7]).Height = 40;

            //-----------end manual control declarations--------------------

            this._controls[1].Text = Event_src;
            this._controls[2].Text = Event;
            this._controls[3].Text = Precondition;
            this._controls[4].Text = actionSource;
            this._controls[5].Text = actionCall;
            this._controls[6].Text = Action_parameter;
            this._controls[7].Text = Postcondition;


            for (int i = 1; i < 8; i++)
            {
                this._controls[i].Name = "txtbx&" + _drawnRuleCount.ToString() + "&" + i.ToString();
                this._controls[i].Dock = DockStyle.Top & DockStyle.Left;
                if (_controls[i].GetType() == typeof(Button))
                {
                    _controls[i].Click += new EventHandler(button_Click);
                    
                }
                else if (_controls[i].GetType() == typeof(ComboBox))
                {
                    ((ComboBox)_controls[i]).DropDown += new EventHandler(ComboBox_DropDown);
                }

                _controls[i].TextChanged += new EventHandler(Control_TextChanged);
            }

            for (int i = 1; i < 8; i++)
            {
                this.tableLayoutPanel1.Controls.Add(this._controls[i], i, _drawnRuleCount);
            }

            tableLayoutPanel1.ResumeLayout();
        }

        #region deprecated
        private void ComboBox_DropDown(object sender, EventArgs e)
        {
            String location = ((ComboBox)sender).Name;
            String[] position = location.Split('&');

            //The X value
            int ruleNumber = int.Parse(position[1]);

            //The Y value
            int column = int.Parse(position[2]);

            switch (column)
            {
                case 2:
                    //Task: populate the events combobox

                    //1. take xpath query
                    String xpathQuery = R2ML.RuleFactory.Instance.ruleBase.ruleSet.reactionRuleList[ruleNumber].triggeringEvent.messageEventExpression.sender;

                    //2. spawn new instances and feed into the application object model.

                    //3. run query and get set of objects.

                    //4. reflect the objects to get event list.

                    //-----temp work around-----

                    ((ComboBox)sender).Items.Add("Click");
                    ((ComboBox)sender).Items.Add("Double Click");

                    break;
                case 4:
                    //possibly change this from a combo box.
                    break;
                default:
                    break;
            }
        } 
        #endregion

        #region Options Form
        /// <summary>
        /// show the Options Form if a button was clicked
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button_Click(object sender, EventArgs e)
        {
            if (_optionsForm != null)
            {
                _optionsForm = null;
            }
            else
            {
                _optionsForm = new Options(((Button)sender).Text);
                _optionsForm.Deactivate += new EventHandler(_optionsForm_Deactivate);
                _clickedButton = sender;

                _optionsForm.Text = ((Button)sender).Name; //sender.ToString();


                //assign the following calaculation to see if there is enough room on screen to place a Form above the clicked button *sender*
                Point location = this.PointToScreen(((Control)sender).Location);

                int i = location.Y - _optionsForm.Height;

                if (i < 0)
                {
                    i = location.Y + ((Control)sender).Height;
                }

                location.Y = i;

                _popupHelper.ShowPopup(this.ParentForm, _optionsForm, location);
            }
        }

        void _optionsForm_Deactivate(object sender, EventArgs e)
        {
            ((Button)_clickedButton).Text = _optionsForm.xpathExpression;
            _optionsForm.Close();
            _optionsForm = null;
        }

        public void optionsForm_Closing(object sender, EventArgs e)
        {
            ((Button)_clickedButton).Text = _optionsForm.xpathExpression;
        } 
        #endregion

        private void Control_TextChanged(object sender, EventArgs e)
        {
            _changingText = true;

            
            

            String location = ((Control)(sender)).Name;
            String[] position = location.Split('&');

            //The X value
            int ruleNumber = int.Parse(position[1]);

            //The Y value
            int column = int.Parse(position[2]);

            _lastFocusedControl = new Point(ruleNumber,column);

            switch (column)
            {
                case 1:
                    //event source

                    RuleFactory.Instance.addReactionRuleTriggeringEvent(ruleNumber, ((Control)sender).Text);
                    ViewUpdateOccured.Invoke();

                    break;

                case 2:
                    //event type

                    //call a method to get a list via reflection on the set of results
                    //reflection_method(((Control)sender).Text);

                    i = new Intellisense(ruleNumber, column);
                    i.List_KeyPressed += new KeyPressEventHandler(Intellisense_PreviewKeyDown);
                    i.List_DoubleClicked += new EventHandler(Intellisense_DoubleClick);
                    i.Show();
                    Point loc = this.PointToScreen(((Control)sender).Location);
                    i.Left = loc.X;
                    i.Top = loc.Y + ((Control)sender).Height;
                    List<String> eventType = new List<String>();
                    eventType.Add(((Control)sender).Text);
                    RuleFactory.Instance.addReactionRuleTriggeringEvent(ruleNumber, eventType);
                    ViewUpdateOccured.Invoke();
                    i.Focus();
                    
                    break;

                case 3:
                    //pre condition

                    RuleFactory.Instance.addReactionRuleConditions(ruleNumber, ((Control)sender).Text);
                    ViewUpdateOccured.Invoke();
                    break;

                case 4:
                    //action Source (query)
                    String actionSourceText = _optionsForm.xpathExpression;

                    RuleFactory.Instance.addReactionRuleProducedAction(ruleNumber, actionSourceText);

                    ViewUpdateOccured.Invoke();
                    break;

                case 5:
                    //property or method declaration
                    String actionCallText = ((Control)sender).Text;

                    //work out if we have a method, or a property
                    if (actionCallText.EndsWith("()"))
                    {
                        //we have a method
                        actionCallText = actionCallText.Remove(actionCallText.Length - 2, 2);
                        RuleFactory.Instance.addReactionRuleProducedAction(ruleNumber, R2ML.RuleFactory.ActionType.method, actionCallText);
                    }
                    else
                    {
                        //we have a property
                        RuleFactory.Instance.addReactionRuleProducedAction(ruleNumber, R2ML.RuleFactory.ActionType.property, actionCallText);

                    }
                    ViewUpdateOccured.Invoke();
                    break;

                case 6:
                    //action parameters
                    String controlText = ((Control)sender).Text;
                    String[] parameters = controlText.Split(',');

                    List<String> types = new List<string>();
                    List<String> values = new List<string>();

                    //our loop iteration variable is effectively readonly so we need to copy it.
                    String workingString;

                    foreach (String parameter in parameters)
                    {
                        workingString = parameter;

                        if (isString(parameter))
                        {
                            workingString = workingString.Remove(0, 1);
                            workingString = workingString.Remove(workingString.Length - 1, 1);
                            types.Add("String");
                            values.Add(parameter);
                        }
                        else
                        {
                            types.Add("");
                            values.Add(parameter);
                        }
                    }

                    RuleFactory.Instance.addReactionRuleProducedAction(ruleNumber, types, values);

                    ViewUpdateOccured.Invoke();
                    break;
                case 7:
                    //postcondition
                    RuleFactory.Instance.addReactionRulePostCondition(ruleNumber, ((Control)sender).Text);
                    ViewUpdateOccured.Invoke();
                    break;
                default:
                    break;
            }      
        }

        void Intellisense_DoubleClick(object sender, EventArgs e)
        {
            List<String> list = new List<String>();

            String s = ((ListBox)sender).SelectedItem.ToString();

            list.Add(s);

            RuleFactory.Instance.addReactionRuleTriggeringEvent(i.RuleNumber, list);

            i.Close();

            ViewUpdateOccured.Invoke();
        }

        void Intellisense_PreviewKeyDown(object sender, KeyPressEventArgs e)
        {
            //if the event type column initialized intellisense
            if (i.Column == 2)
            {
                //append the key character to the string of the textbox being intellisensed.

                List<String> list = new List<String>();

                String s = RuleFactory.Instance.ruleBase.ruleSet.reactionRuleList[i.RuleNumber-1].triggeringEvent.messageEventExpression.eventType + e.KeyChar.ToString();
                
                list.Add(s);

                RuleFactory.Instance.addReactionRuleTriggeringEvent(i.RuleNumber, list);

                ViewUpdateOccured.Invoke();
            }
        }

        /// <summary>
        /// Check to see if the input is intended to be the type of string.
        /// </summary>
        /// <param name="str">a String that is to be tested to see if starts and ends with double quotes</param>
        /// <returns>true if starting and ending with quotes, otherwise false.</returns>
        private Boolean isString(String str)
        {
            if (str.StartsWith("\"") && str.EndsWith("\"") && str.Length > 2)
            {
                return true;
            }

            return false;
        }

        private void NewRule_Click(object sender, EventArgs e)
        {
            NewRule();
        }

        #region syncronization

        /// <summary>
        /// Update the text document(code view) that is associated with this designer
        /// </summary>
        public string getXML()
        {
            //
            updatingOnUserEdit = true;

            String contents = RuleFactory.Instance.SerializeRules();

            updatingOnUserEdit = false;

            return contents;
        }

        //public void updateUI(String text, Uri URI)
        //{
        //    updateUI(text);
        //}

        /// <summary>
        /// See if the input string is valid/invalid/empty accprding to the r2ml schema.
        /// </summary>
        public void updateUI(String text)
        {
            //TODO: complete this method.
            XmlDocument xmlDoc = new XmlDocument();
            Boolean emptyDocument = false;

            try
            {
                //if the document has no root element then it will fail this try statement.
                xmlDoc.LoadXml(text);
                emptyDocument = false;
            }
            catch (System.Xml.XmlException exception)
            {
                if (exception.Message == "Root element is missing.")
                {
                    emptyDocument = true;

                    //document appears empty.
                    updateError("The Document appears empty to generate a new document [click here]",UpdateErrorType.EmptyDocument);
                }
                
            }
            
            if (emptyDocument == false)
            {
                Boolean validR2ml;
                try
                {
                    //1 Parse the test into rule objects
                    RuleFactory.Instance.LoadRules(text);

                    validR2ml = true;
                }
                catch (Exception)
                {
                    validR2ml = false;
                    updateError("The XML is not valid with the XML schema. Please fix before using a design view. [Details]",UpdateErrorType.InvalidR2ML);
                }

                //if the r2ml is valid then proceded with updating UI otherwise it was caught in the catch statement.
                if (validR2ml)
                {
                    //2 Clear the UI of old rules
                    ClearUI();
                    
                    //3 RedrawUI
                    UpdateUIControls();

                    splitContainer1.Show();
                    errorlabel.Hide();
                    errorlinkLabel.Hide();

                    RestoreFocus();
                }

            }

        }

        #endregion

        /// <summary>
        /// restore focus to the component that lost it from being updated.
        /// </summary>
        /// <param name="row"></param>
        /// <param name="column"></param>
        private void RestoreFocus()
        {
            Control control = getControlByName("txtbx&" + _lastFocusedControl.X.ToString() + "&" + _lastFocusedControl.Y.ToString());

            if (control != null)
            {
                ((TextBox)control).Focus();
                ((TextBox)control).DeselectAll();
                ((TextBox)control).SelectionStart = ((TextBox)control).Text.Length;
                 
            }
        }

        private Control getControlByName(String name)
        {
            Control[] controlList = this.Controls.Find(name, true);

            if (controlList.Length > 1)
            {
                throw new Exception("Expected one result, but received none or many");
            }
            else if (controlList.Length < 1)
            {
                return null;
            }

            return controlList[0];
        }

        



        private void updateError(String message, UpdateErrorType type)
        {
            splitContainer1.Hide();
            errorlabel.Show();
            errorlinkLabel.Show();

            this.Controls.Add(errorlabel);
            this.Controls.Add(errorlinkLabel);

            int startPosOfLink =0, endPosOfLink = 0;

            for (int i = 0; i < message.Length; i++)
            {
                if (message[i] == '[')
                {
                    startPosOfLink = i;
                }
                else if (message[i] == ']')
                {
                    endPosOfLink = i;
                    break;
                }
            }

            if (endPosOfLink < 1)
            {
                throw new Exception("Problem parsing the Link tag.");
            }

            errorlabel.Text = message.Substring(0, startPosOfLink);
            errorlinkLabel.Text = message.Substring(startPosOfLink + 1, endPosOfLink - startPosOfLink-1);

            //-----------------------
            //Error Label Layout data
            //-----------------------

            errorlabel.Width = Util.GetPixelLengthFromString(errorlabel.Text, errorlabel.Font);
            errorlinkLabel.Width = Util.GetPixelLengthFromString(errorlinkLabel.Text,errorlinkLabel.Font);

            try { errorlabel.Left = (this.Width - errorlabel.Width - errorlinkLabel.Width)/2; }
            catch (Exception) { errorlabel.Left = 0; }

            errorlabel.Top = (this.Height / 2) - (errorlinkLabel.Height / 2);


            errorlinkLabel.Left = errorlabel.Left + errorlabel.Width;
            errorlinkLabel.Top = errorlabel.Top;

            //--------------------------
            //Link Label Action Handlers
            //--------------------------

            switch (type)
            {
                case UpdateErrorType.EmptyDocument:
                    //Display a message to say that there is an empty document with a link
                    //the link should allow the creation of a basic editable document.

                    errorlinkLabel.Click += new EventHandler(delegate {
                    CreateNewDocument();
                    });
                    break;
                case UpdateErrorType.InvalidR2ML:
                    //Display a message saying there is syntax error with the r2ml document.
                    //Offer a stacktrace via a link. Suggest fixing it by the xml view.

                    errorlinkLabel.Click += new EventHandler(delegate {
                    errorlabel.Text += "Stack Trace Goes here";
                    });
                    break;
                case UpdateErrorType.Message:
                    //This is just a plain text message to display.
                    throw new Exception("Method not implemented yet");
                    break;
                default:
                    //it shouldn't be possible to get here.
                    throw new Exception("Unexpected Update Error Type");
                    break;
            }
        }

        private void CreateNewDocument()
        {
            //add a blank Reaction Rule
            RuleFactory.Instance.addReactionRule("rule1");
            RuleFactory.Instance.ruleBase.ruleSet.reactionRuleList[0].conditions = "";
            RuleFactory.Instance.ruleBase.ruleSet.reactionRuleList[0].Documentation = new Documentation();
            RuleFactory.Instance.ruleBase.ruleSet.reactionRuleList[0].Documentation.SourceCode = new SourceCode();
            RuleFactory.Instance.ruleBase.ruleSet.reactionRuleList[0].Documentation.SourceCode.MethodInstance = new SourceCode.Method();
            RuleFactory.Instance.ruleBase.ruleSet.reactionRuleList[0].Documentation.SourceCode.MethodInstance.Name = "method1";
            
            RuleFactory.Instance.ruleBase.ruleSet.reactionRuleList[0].postcondition = new PostCondition();
            RuleFactory.Instance.ruleBase.ruleSet.reactionRuleList[0].postcondition.objectClassificationAtom = new ObjectClassificationAtom();
            RuleFactory.Instance.ruleBase.ruleSet.reactionRuleList[0].postcondition.objectClassificationAtom.arguements = new ObjectVariable[1];
            RuleFactory.Instance.ruleBase.ruleSet.reactionRuleList[0].postcondition.objectClassificationAtom.arguements[0] = new ObjectVariable();
            RuleFactory.Instance.ruleBase.ruleSet.reactionRuleList[0].postcondition.objectClassificationAtom.arguements[0].name = "";

            RuleFactory.Instance.ruleBase.ruleSet.reactionRuleList[0].producedAction = new ProducedAction();
            RuleFactory.Instance.ruleBase.ruleSet.reactionRuleList[0].producedAction.assignActionExpression = new ProducedAction.AssignActionExpression();
            RuleFactory.Instance.ruleBase.ruleSet.reactionRuleList[0].producedAction.assignActionExpression.arguements = new TypedLiteral[1];
            RuleFactory.Instance.ruleBase.ruleSet.reactionRuleList[0].producedAction.assignActionExpression.arguements[0] = new TypedLiteral();
            RuleFactory.Instance.ruleBase.ruleSet.reactionRuleList[0].producedAction.assignActionExpression.arguements[0].datatypeID = "";
            RuleFactory.Instance.ruleBase.ruleSet.reactionRuleList[0].producedAction.assignActionExpression.arguements[0].lexicalValue = "";
            RuleFactory.Instance.ruleBase.ruleSet.reactionRuleList[0].producedAction.assignActionExpression.contextArguement = new ObjectVariable[1];
            RuleFactory.Instance.ruleBase.ruleSet.reactionRuleList[0].producedAction.assignActionExpression.contextArguement[0] = new ObjectVariable();
            RuleFactory.Instance.ruleBase.ruleSet.reactionRuleList[0].producedAction.assignActionExpression.contextArguement[0].name = "";
            RuleFactory.Instance.ruleBase.ruleSet.reactionRuleList[0].producedAction.assignActionExpression.propertyID = "";
            
            RuleFactory.Instance.ruleBase.ruleSet.reactionRuleList[0].triggeringEvent = new TriggeringEvent();
            RuleFactory.Instance.ruleBase.ruleSet.reactionRuleList[0].triggeringEvent.messageEventExpression = new TriggeringEvent.MessageEventExpression();
            RuleFactory.Instance.ruleBase.ruleSet.reactionRuleList[0].triggeringEvent.messageEventExpression.sender = "";
            RuleFactory.Instance.ruleBase.ruleSet.reactionRuleList[0].triggeringEvent.messageEventExpression.arguements = new ObjectVariable[1];
            RuleFactory.Instance.ruleBase.ruleSet.reactionRuleList[0].triggeringEvent.messageEventExpression.arguements[0] = new ObjectVariable();
            RuleFactory.Instance.ruleBase.ruleSet.reactionRuleList[0].triggeringEvent.messageEventExpression.arguements[0].name = "";
            RuleFactory.Instance.ruleBase.ruleSet.reactionRuleList[0].triggeringEvent.messageEventExpression.eventType = "";

            //trigger an update
            ViewUpdateOccured.Invoke();

        }

        #region Hide/Show Columns

        private void ToggleColumns_Click(object sender, EventArgs e)
        {
            if (!_columnshidden)
            {
                hideConditionColumns();
            }
            else
            {
                showConditionColumns();
            }
        }

        private void hideConditionColumns()
        {
            ColumnStyle cs = new ColumnStyle(SizeType.Absolute, 1);
            ColumnStyle cs2 = new ColumnStyle(SizeType.Absolute, 1);

            tableLayoutPanel1.SuspendLayout();
            tableLayoutPanel1.ColumnStyles[3] = cs;
            tableLayoutPanel1.ColumnStyles[7] = cs2;
            tableLayoutPanel1.ResumeLayout();
            _columnshidden = true;
        }

        private void showConditionColumns()
        {
            ColumnStyle cs = new ColumnStyle(SizeType.Percent, 16);
            ColumnStyle cs2 = new ColumnStyle(SizeType.Percent, 17);

            tableLayoutPanel1.SuspendLayout();
            tableLayoutPanel1.ColumnStyles[3] = cs;
            tableLayoutPanel1.ColumnStyles[7] = cs2;
            tableLayoutPanel1.ResumeLayout();
            _columnshidden = false;
        } 

        #endregion

        #region Member Types

        enum UpdateErrorType{InvalidR2ML,EmptyDocument,Message}

        #endregion

        #region Member Variables

        Point _lastFocusedControl;
        Intellisense i;
        Label errorlabel = new Label();
        LinkLabel errorlinkLabel = new LinkLabel();
        int _drawnRuleCount = 0;
        bool _columnshidden = true;
        bool _changingText = false;
        Control[] _controls;
        Label _labelInst;
        Options _optionsForm = null;
        object _clickedButton;
        PopupWindowHelper _popupHelper = new PopupWindowHelper();

        #endregion
    }
}